

class CanFrame:

    id = 0
    name = '(no name)'
    length = 0
    node = '(no node)'

    def __init__(self, info):
        self.id = int(info[1])
        self.name = info[2][:-1]
        self.length = int(info[3])
        self.node = info[4]

    def to_dict(self):
        item = {
            'id': self.id,
            'name': self.name,
            'length': self.length,
            'node': self.node,
        }
        return item


class CanSignal:

    name = '(no name)'
    fullname = '(name_id)'
    frame_id = 0
    start_pos = 0
    bit_length = 0
    # TODO:
    scale = 1.0
    offset = 0.0
    unit = 'TODO'
    comment = 'TODO'

    def __init__(self, info, frame_id, frame_name):
        self.name = info[1]
        self.fullname = frame_name + '___' + self.name
        self.frame_id = frame_id
        pos = info[3].split("@")
        pos = pos[0].split("|")
        self.start_pos = int(pos[0])
        self.bit_length = int(pos[1])

    def to_dict(self):
        item = {
            'name': self.name,
            'fullname': self.fullname,
            'frame_id': self.frame_id,
            'start_pos': self.start_pos,
            'bit_length': self.bit_length,
        }
        return item


class DbcReader:

    log = None
    curr_frame = None
    frame_list = []
    signal_list = []

    def __init__(self):
        self.log = open("dbg_reader.log", 'w')

    def __del__(self):
        self.log.close()

    def parse_frame(self, info):
        frame = CanFrame(info)
        self.frame_list.append(frame)
        print("[FRAME] %s" % frame.to_dict(), file=self.log)
        self.curr_frame = frame

    def parse_signal(self, info):
        signal = CanSignal(info, self.curr_frame.id, self.curr_frame.name)
        self.signal_list.append(signal)
        print("[SIGNAL] %s" % signal.to_dict(), file=self.log)

    def parse_dbc(self, dbc):
        line = dbc.readline()
        while line != '':
            info = line.split()
            if len(info) > 0:
                if info[0] == 'BO_':
                    self.parse_frame(info)
                elif info[0] == 'SG_':
                    self.parse_signal(info)
                else:
                    print("[IGNORE]%s" % line[:-1], file=self.log)
            line = dbc.readline()

    def load_file(self, dbc_path):
        print("load file: %s" % dbc_path, file=self.log)
        # clear lists
        self.curr_frame = None
        self.frame_list.clear()
        self.signal_list.clear()
        # open dbc file
        dbc = open(dbc_path, 'r')
        # parse dbc file
        self.parse_dbc(dbc)
        # close dbc file
        dbc.close()


dbcReader = DbcReader()


if __name__ == '__main__':
    dbcReader.load_file("../../variant_gac/config/CANFD_09.dbc")
